﻿// Original author contact info: Owen Emlen (owene_1998@yahoo.com)
// Note: other individuals may also have contributed to this code
// Project hosted on CodePlex.com as of 1/10/2009 at http://www.codeplex.com/EmlenMud
using System.Runtime.Serialization;
using System;
using System.Xml.Serialization;
using System.ComponentModel;
using System.Collections.Generic;
using System.Reflection;
using BrainTechLLC.ThreadSafeObjects;
using BrainTechLLC;
#if USE_HYPER
using Hyper.ComponentModel;
#endif

namespace BrainTechLLC.ThreadSafeObjects
{
	[Serializable]
	[DataContract]
	public class ThreadSafeLookupOnDemandWithDelegate<T1, T2> : ThreadSafeLookup<T1, T2> where T2 : class
	{
		[NonSerialized, XmlIgnore]
		protected Cached<List<T2>> _cachedList;

		public ThreadSafeLookupOnDemandWithDelegate() { }
		public ThreadSafeLookupOnDemandWithDelegate(StringComparer comparer)
			: base(comparer)
		{
		}

		public Cached<List<T2>> CachedList
		{
			get
			{
				return Populate.OnDemand<Cached<List<T2>>>(ref _cachedList, () => new Cached<List<T2>>(
					 delegate(object param, out List<T2> result, object[] args) { result = base.AllItems; return true; }));
			}
		}

		public void MarkDirty()
		{
			if (_cachedList != null)
				_cachedList.MarkDirty();
		}

		public new List<T2> AllItems { get { return CachedList.GetItem(); } }

		public new void AddOrSet(T1 key, T2 item)
		{
			base.AddOrSet(key, item);

			MarkDirty();
		}

		public T2 Get(T1 key, Func<T1, T2> func)
		{
			T2 item = this[key];

			if (item == null)
			{
				item = func(key);
				base.AddOrSet(key, item);

				if (_cachedList != null)
					_cachedList.MarkDirty();
			}

			return item;
		}
	}
}

